package org.kiwi.util.log.support;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;

/**
 * @email jack.liu.19910921@gmail.com
 * Created by jack on 17/6/7.
 */
public class EnhancedLoggerFactory {

    public static Logger getLogger(Class clz) {
        Logger logger = LoggerFactory.getLogger(clz);

        return (Logger) Proxy.newProxyInstance(EnhancedLoggerFactory.class.getClassLoader(),
                new Class[]{Logger.class}, new EnhancedLoggerInvocationHandler(logger));
    }

    private static class EnhancedLoggerInvocationHandler implements InvocationHandler {

        Object target;

        public EnhancedLoggerInvocationHandler(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            doWrapMessageIfNecessary(method, args);

            return method.invoke(target, args);
        }

        private static final String DEBUG = "debug";
        private static final String ERROR = "error";
        private static final String TRACE = "trace";
        private static final String INFO = "info";
        private static final String WARN = "warn";

        private static final List<String> METHODS = Arrays.asList(DEBUG, ERROR, TRACE, INFO, WARN);

        private void doWrapMessageIfNecessary(Method method, Object[] args) {
            if (METHODS.contains(method.getName())) {
                Class<?>[] typeParameters = method.getParameterTypes();
                for (int i = 0; i < typeParameters.length; i++) {
                    if (typeParameters[i] == String.class) {
                        args[i] = doWrapMessage(args[i] + "");
                    }
                }
            }
        }

        private String doWrapMessage(String msg) {
            String prefix = EnhancedLoggerManager.getPrefix();
            String suffix = EnhancedLoggerManager.getSuffix();

            StringBuffer sb = new StringBuffer();
            if (StringUtils.isNotBlank(prefix)) {
                sb.append(" [")
                        .append(prefix)
                        .append("] ");
            }
            sb.append(msg);
            if (StringUtils.isNotBlank(suffix)) {
                sb.append(">>>")
                        .append(" [")
                        .append(suffix)
                        .append("] ");
            }
            return sb.toString();
        }

    }

}
